﻿namespace vkUpploaderApp
{
    using System;
    using System.IO;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    using vkUpploaderLib;
    using vkUpploaderLib.Exceptions;
    using vkUpploaderLib.Objects;

    internal class WebUploader
    {
        private Control _mainThreadHandle;

        private NotifyIcon _notifyIcon;

        public WebUploader(Control mainThreadHandle, NotifyIcon notifyIcon)
        {
            _mainThreadHandle = mainThreadHandle;
            _notifyIcon = notifyIcon;
        }

        public event MethodInvoker Completed;

        public event EventHandler<ExceptionEventArgs> Exception;

        public void Start(string fileName, bool deleteFile)
        {
            Task.Factory.StartNew(() => InternalStart(fileName, deleteFile));
        }

        private void InternalStart(string fileName, bool deleteFile, bool isRecursiveEntry = false)
        {
            Photo photo = null;

            try {
                photo = ApiHelper.UploadImage(fileName, Properties.Settings.Default.DefaultAlbum.Id, Properties.Settings.Default.DefaultTargetId);
            }
            catch (Exception ex) {
                var exception = ex as VkException;
                if (exception != null && !isRecursiveEntry) {
                    if (exception.Code == VkExceptionsEnum.UserAuthorizationFailed) {
                        if (OnMainThread((Func<bool>)WebUploaderOnUserAuthorizationFailed)) {
                            InternalStart(fileName, deleteFile, true);
                            return;
                        }
                    }
                }
                else {
                    Exception(this, new ExceptionEventArgs(ex));
                }
            }

            if (deleteFile) {
                TryDeleteFile(fileName);
            }

            if (photo != null) {
                OnMainThread(() => Clipboard.SetText(photo.BiggestSrc));
                OnMainThread(() => WebUpploaderUrlSetInClipboard());
            }

            OnMainThread(() => Completed());
        }

        private void TryDeleteFile(string fileName)
        {
            try {
                File.Delete(fileName);
            }
            catch (Exception) {}
        }

        private void WebUpploaderUrlSetInClipboard()
        {
            _notifyIcon.ShowBalloonTip(2000, StringResources.ProductName, StringResources.UrlCopiedToClipboard, ToolTipIcon.Info);
        }

        private bool OnMainThread(Func<bool> func)
        {
            bool result = false;
            _mainThreadHandle.Invoke((Action)(() => result = func()));
            return result;
        }

        private void OnMainThread(Action action)
        {
            _mainThreadHandle.Invoke(action);
        }

        private bool WebUploaderOnUserAuthorizationFailed()
        {
            var result = AuthHelper.Auth();
            if (result) {
                Properties.Settings.Default.Token = AuthHelper.Token;
                Properties.Settings.Default.TokenExpires = AuthHelper.TokenExpires;
                Properties.Settings.Default.UserID = AuthHelper.UserID;
                Properties.Settings.Default.Save();
            }
         
            return result;
        }
    }
}